package pers.duorhs.easierfeign.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import pers.duorhs.easierfeign.annotation.EasierFeignService;
import pers.duorhs.easierfeign.invoker.EasierFeignServiceInvoker;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Duorhs
 * @date 2022/1/10 11:31
 */
@Configuration
@EnableConfigurationProperties(EasierFeignProperties.class)
@ConditionalOnProperty(prefix = "easierfeign", name = "isProvider", havingValue = "true")
public class EasierFeignProviderConfiguration {
    private final ConcurrentHashMap<String, Object> serviceMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Method> methodMap = new ConcurrentHashMap<>();

    @Autowired
    public EasierFeignProviderConfiguration(ApplicationContext applicationContext) {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(EasierFeignService.class);
        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            String name = entry.getKey();
            Object service = entry.getValue();
            StringBuilder sb = new StringBuilder(name);
            sb.replace(0, 1, name.substring(0, 1).toUpperCase());
            if (name.endsWith("Impl")) {
                sb.delete(name.length() - 4, name.length());
            }
            name = sb.toString();
            serviceMap.put(name, service);
            for (Method method : service.getClass().getDeclaredMethods()) {
                if (!method.getName().startsWith("CGLIB") && method.canAccess(service)) {
                    this.methodMap.put(name + "#" + method.getName(), method);
                }
            }
        }
    }

    @Bean(name = "EasierFeignServiceMap")
    public ConcurrentHashMap<String, Object> getServiceMap() {
        return serviceMap;
    }

    @Bean(name = "EasierFeignMethodMap")
    public ConcurrentHashMap<String, Method> getMethodMap() {
        return methodMap;
    }

    @Bean(name = "EasierFeignServiceInvoker")
    public EasierFeignServiceInvoker getEasierFeignServiceInvoker() {
        return new EasierFeignServiceInvoker();
    }

}
